package com.qiaofang.applet.service.property.service.impl;

import com.google.common.collect.Lists;
import com.mongodb.client.result.UpdateResult;
import com.qiaofang.applet.common.base.BaseDomain;
import com.qiaofang.applet.common.base.MongoBaseService;
import com.qiaofang.applet.constants.PropertyRedundanceFieldEnum;
import com.qiaofang.applet.service.member.domain.Department;
import com.qiaofang.applet.service.member.domain.Employee;
import com.qiaofang.applet.service.member.repository.DepartmentRepository;
import com.qiaofang.applet.service.member.service.EmployeeService;
import com.qiaofang.applet.service.property.domain.*;
import com.qiaofang.applet.service.property.repository.PropertyRepository;
import com.qiaofang.applet.service.property.service.PropertyContactService;
import com.qiaofang.applet.service.property.service.PropertyDataHandleService;
import com.qiaofang.applet.service.property.service.QueryCommonService;
import com.qiaofang.applet.service.property.service.dto.PropertyRedundanceFieldDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author QF2019
 */
@Slf4j
@Service
public class PropertyDataHandleServiceImpl extends MongoBaseService<Property, String> implements PropertyDataHandleService, QueryCommonService {

    private final PropertyRepository propertyRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private DepartmentRepository departmentRepository;

    @Autowired
    private PropertyContactService propertyContactService;

    public PropertyDataHandleServiceImpl(PropertyRepository propertyRepository) {
        super(propertyRepository);
        this.propertyRepository = propertyRepository;
    }

    @Override
    public void initAllPropertyRedundanceField(List<Property> propertys) {

        if (CollectionUtils.isEmpty(propertys)){
            return;
        }

        for (Property property : propertys) {
            initPropertyRedundanceField(property);
        }
    }

    @Override
    public void updatePropertyRedundanceField(List<PropertyRedundanceFieldDto> redundanceFieldDtos) {
        if(CollectionUtils.isEmpty(redundanceFieldDtos)){
            return;
        }
        for(PropertyRedundanceFieldDto redundanceFieldDto : redundanceFieldDtos) {
            try {
                Query query = createFindQuery(new PropertyRedundanceFieldDto(redundanceFieldDto.getCompanyUuid(),
                        redundanceFieldDto.getPropertyRedundanceField(), redundanceFieldDto.getFieldUuid(), null));
                Update update = new Update();
                // 不是VR，走通用逻辑
                if (PropertyRedundanceFieldEnum.VR.equals(redundanceFieldDto.getPropertyRedundanceField())) {
                    // 是VR，先查下出vr信息，再更新字段
                    PropertyVr propertyVr = getOne(query, PropertyVr.class);
                    update.set("vrImgUrl", propertyVr == null ? null : propertyVr.getPreview());
                    update.set("vrUrl", propertyVr == null ? null : propertyVr.getRoamview());
                    update.set("existVr", propertyVr == null ? false : true);
                } else if (PropertyRedundanceFieldEnum.VIDEO.equals(redundanceFieldDto.getPropertyRedundanceField())) {
                    PropertyVideo propertyVideo = getOne(query, PropertyVideo.class);
                    update.set("videoUrl", propertyVideo == null ? null : propertyVideo.getVideoUrl());
                    update.set("coverPhotoUrl", propertyVideo == null ? null : propertyVideo.getCoverPhotoUrl());
                } else if (PropertyRedundanceFieldEnum.CONTACT.equals(redundanceFieldDto.getPropertyRedundanceField())) {
                    // CONTACT
                    PropertyContact propertyContact = new PropertyContact();
                    propertyContact.setCompanyUuid(redundanceFieldDto.getCompanyUuid());
                    propertyContact.setPropertyUuid(redundanceFieldDto.getFieldUuid());
                    propertyContact.setDeleted(false);
                    Iterable<PropertyContact> allContacts = propertyContactService.findAll(Example.of(propertyContact));
                    ArrayList<PropertyContact> propertyContacts = Lists.newArrayList(allContacts);
                    if(!CollectionUtils.isEmpty(propertyContacts)){
                        String ownerPhone= propertyContacts.stream().filter(f -> StringUtils.isNotBlank(f.getPhone1()) || StringUtils.isNotBlank(f.getPhone2())).map(item->{
                            StringBuffer sb=new StringBuffer();
                            if(StringUtils.isNotBlank(item.getPhone1())){
                                sb.append(item.getPhone1());
                                sb.append("|");
                            }
                            if(StringUtils.isNotBlank(item.getPhone2())){
                                sb.append(item.getPhone2());
                                sb.append("|");
                            }
                            return sb.toString();
                        }).collect(Collectors.joining("|"));
                        update.set("ownerPhone", StringUtils.isBlank(ownerPhone) ? null : ownerPhone);
                    }
                } else {
                    update.set(redundanceFieldDto.getPropertyRedundanceField().getUpdateField(), redundanceFieldDto.getFieldValue());
                }
                update.set("updateTime", new Date());

                UpdateResult result = mongoTemplate.updateMulti(query, update, Property.class);
                log.info("冗余字段更新完毕, 字段名：{}，修改条数：{}", redundanceFieldDto.getPropertyRedundanceField(), result.getMatchedCount());
            } catch (Exception e) {
                log.error("冗余字段更新失败, 字段名：{}, 错误日志：{}", redundanceFieldDto.getPropertyRedundanceField(), e);
            }
        }
    }

    @Override
    public void initPropertyRedundanceField(Property property) {
        // 楼盘
        Estate estate = getOne(createFindQuery(new PropertyRedundanceFieldDto(property.getCompanyUuid(),
                PropertyRedundanceFieldEnum.ESTATE, property.getEstateUniqueUuid(), null)), Estate.class);
        if (estate != null) {
            // 商圈
            Area area = getOne(createFindQuery(new PropertyRedundanceFieldDto(property.getCompanyUuid(),
                    PropertyRedundanceFieldEnum.AREA, estate.getAreaUuid(), null)), Area.class);
            if (area != null) {
                property.setAreaName(area.getAreaName());
                property.setAreaUuid(area.getAreaUuid());
            }
        }
        // VR
        PropertyVr propertyVr = getOne(createFindQuery(new PropertyRedundanceFieldDto(property.getCompanyUuid(),
                PropertyRedundanceFieldEnum.VR, property.getPropertyUuid(), null)), PropertyVr.class);
        if (propertyVr != null) {
            property.setVrImgUrl(propertyVr.getPreview());
            property.setVrUrl(propertyVr.getRoamview());
            property.setExistVr(true);
        } else {
            property.setExistVr(false);
        }

        // VIDEO
        PropertyVideo propertyVideo = getOne(createFindQuery(new PropertyRedundanceFieldDto(property.getCompanyUuid(),
                PropertyRedundanceFieldEnum.VIDEO, property.getPropertyUuid(), null)), PropertyVideo.class);
        if (propertyVideo != null) {
            property.setVideoUrl(propertyVideo.getVideoUrl());
            property.setCoverPhotoUrl(propertyVideo.getCoverPhotoUrl());
        }

        // CONTACT
        PropertyContact propertyContact = new PropertyContact();
        propertyContact.setCompanyUuid(property.getCompanyUuid());
        propertyContact.setPropertyUuid(property.getPropertyUuid());
        propertyContact.setDeleted(false);
        Iterable<PropertyContact> allContacts = propertyContactService.findAll(Example.of(propertyContact));
        ArrayList<PropertyContact> propertyContacts = Lists.newArrayList(allContacts);
        if(!CollectionUtils.isEmpty(propertyContacts)){
            String ownerPhone= propertyContacts.stream().filter(f -> StringUtils.isNotBlank(f.getPhone1()) || StringUtils.isNotBlank(f.getPhone2())).map(item->{
                StringBuffer sb=new StringBuffer();
                if(StringUtils.isNotBlank(item.getPhone1())){
                    sb.append(item.getPhone1());
                    sb.append("|");
                }
                if(StringUtils.isNotBlank(item.getPhone2())){
                    sb.append(item.getPhone2());
                    sb.append("|");
                }
                return sb.toString();
            }).collect(Collectors.joining("|"));
            property.setOwnerPhone(ownerPhone);
        }
        // 初始化归属人1,2,3姓名
        initEmployeeName(property);

        // 初始化归属人1，2，3部门名称
        initDeptName(property);

    }

    /**
     * 根据条件查询数据
     * @param query
     * @param t
     * @param <T>
     * @return
     */
    private <T extends BaseDomain> T getOne(Query query, Class<T> t) {
        List<T> datas = (List<T>) mongoTemplate.find(query, t);
        return !CollectionUtils.isEmpty(datas) ? datas.get(0) : null;
    }

    /**
     * 创建查询条件
     * @param propertyRedundanceFieldDto
     * @return
     */
    private Query createFindQuery(PropertyRedundanceFieldDto propertyRedundanceFieldDto) {
        Query query = new Query();
        Criteria criteria = Criteria.where("companyUuid").is(propertyRedundanceFieldDto.getCompanyUuid());
        criteria.and(propertyRedundanceFieldDto.getPropertyRedundanceField().getQueryField()).is(propertyRedundanceFieldDto.getFieldUuid());
        query.addCriteria(criteria);
        return query;
    }

    /**
     * 初始化归属人姓名
     * @return
     */
    private void initEmployeeName(Property property) {
        if(StringUtils.isEmpty(property.getCompanyUuid())){
            return;
        }
        Set<String> employeeUuids = new HashSet<>();
        if(StringUtils.isNotEmpty(property.getEmployeeUuid1())) {
            employeeUuids.add(property.getEmployeeUuid1());
        }
        if(StringUtils.isNotEmpty(property.getEmployeeUuid2())) {
            employeeUuids.add(property.getEmployeeUuid2());
        }
        if(StringUtils.isNotEmpty(property.getEmployeeUuid3())) {
            employeeUuids.add(property.getEmployeeUuid3());
        }
        if(CollectionUtils.isEmpty(employeeUuids)) {
            return;
        }

        List<Employee> employees = employeeService.findAllByEmployeeUuidInAndCompanyUuid(new ArrayList<>(employeeUuids), property.getCompanyUuid());
        if(CollectionUtils.isEmpty(employees)){
            return;
        }

        Map<String, String> empMap = new HashMap<>();
        for(Employee employee : employees) {
           empMap.put(employee.getEmployeeUuid(), employee.getEmployeeName());
        }

        if(StringUtils.isNotEmpty(property.getEmployeeUuid1())) {
            property.setEmployeeUuid1Name(StringUtils.defaultString(empMap.get(property.getEmployeeUuid1())));
        }
        if(StringUtils.isNotEmpty(property.getEmployeeUuid2())) {
            property.setEmployeeUuid2Name(StringUtils.defaultString(empMap.get(property.getEmployeeUuid2())));
        }
        if(StringUtils.isNotEmpty(property.getEmployeeUuid3())) {
            property.setEmployeeUuid3Name(StringUtils.defaultString(empMap.get(property.getEmployeeUuid3())));
        }

    }

    /**
     * 初始化部门名称
     * @param property
     * @return
     */
    private void initDeptName(Property property) {
        if(StringUtils.isEmpty(property.getCompanyUuid())){
            return;
        }
        Set<String> deptUuids = new HashSet<>();
        if(StringUtils.isNotEmpty(property.getDeptUuid1())) {
            deptUuids.add(property.getDeptUuid1());
        }
        if(StringUtils.isNotEmpty(property.getDeptUuid2())) {
            deptUuids.add(property.getDeptUuid2());
        }
        if(StringUtils.isNotEmpty(property.getDeptUuid3())) {
            deptUuids.add(property.getDeptUuid3());
        }
        if(CollectionUtils.isEmpty(deptUuids)) {
            return;
        }

        List<Department> departments = departmentRepository.findListByDeptUuidInAndCompanyUuid(new ArrayList<>(deptUuids), property.getCompanyUuid());

        if(CollectionUtils.isEmpty(deptUuids)){
            return;
        }

        Map<String, String> deptMap = new HashMap<>();
        for(Department department : departments) {
            deptMap.put(department.getDeptUuid(), department.getDeptName());
        }

        if(StringUtils.isNotEmpty(property.getDeptUuid1())) {
            property.setDeptName1(deptMap.get(property.getDeptUuid1()));
        }
        if(StringUtils.isNotEmpty(property.getDeptUuid2())) {
            property.setDeptName2(deptMap.get(property.getDeptUuid2()));
        }
        if(StringUtils.isNotEmpty(property.getDeptUuid3())) {
            property.setDeptName3(deptMap.get(property.getDeptUuid3()));
        }
    }
}
